# -*- coding: utf-8 -*-
'''
Created on 2016-8-5

@author: root
'''

from redis_config import RedisConfig
from redis_config import MARKTDATA_TO_RedisDB
import redis
import pandas as pd
from ..const import STDMARKT_TO_INNER, DATA_FREQUENCY,DATABASES
# from const  import STDMARKT_TO_INNER, DATA_FREQUENCY,DATABASES
import MySQLdb

class RedisDataReader(object):
    '''
    classdocs
    '''
    def __init__(self, _redisConfig):
        '''
        Constructor
        '''
        self.RedisConfig = _redisConfig
        self.redisClt = redis.Redis(host=_redisConfig.host, port=_redisConfig.port, password=_redisConfig.password, db=_redisConfig.db)
        self.conn = MySQLdb.connect(host=DATABASES["hqdata"].get("host"), user=DATABASES["hqdata"].get("user"), passwd=DATABASES["hqdata"].get("password"), db=DATABASES["hqdata"].get("db"), charset="utf8")
        
        '''
          @note: 获取交易日期
           同过获取上证指数的交易日期就可以获得沪深A股的交易日期
       ''' 
    def getTradeDate(self):
        code = '000001.XSHG'
        codeid = self.__redisPrefix('1d') + self.__generateUniqueID(code)
        klines = self.redisClt.zrange(codeid, 0, -1)
        if len(klines) == 0:
            raise RuntimeError('No data for {}'.format(codeid))
        dateset = []
        for kline in klines:
            date = str(kline)
            dateset.append(pd.Timestamp(date[:8]))
        return pd.Index(dateset)
    
    '''
    @function: getKlineData 获取个股的K线数据
    @param  frequency:周期 1m- 1分钟K线,1d- 日K
            order_book_id: 股票id:eg 600869.XSHG
    '''
    def getAllKlineData(self, order_book_id, frequency, fill=True):
        codeid = self.__redisPrefix(frequency) + self.__generateUniqueID(order_book_id)

        klines = self.redisClt.zrange(codeid, 0, -1)
        if len(klines) == 0:
            raise RuntimeError('{0},{1} has no data'.format(order_book_id, frequency))
        dateset = []
        highset = []
        openset = []
        lowset = []
        closeset = []
        volume = []
        temp = ''
        for kline in klines: 
                tmp = str(kline)
                new = tmp[:-1]
                tmplist = new.split(' ')
                if frequency == '1d':
                    dateset.append(tmplist[0]) 
                else:
                    temp_int = int(tmplist[0])
                    temp_int = (2000 + temp_int / 100000000) * 100000000 + (temp_int % 100000000)       
                    tmplist[0] = str(temp_int)
                    if temp == tmplist[0]:
                        continue
                    else:
                        temp = tmplist[0]
                        dateset.append(tmplist[0])
                openset.append(round(float(tmplist[1]), 2))
                highset.append(round(float(tmplist[2]), 2))
                lowset.append(round(float(tmplist[3]), 2))
                closeset.append(round(float(tmplist[4]), 2))
                volume.append(round(float(tmplist[6]), 2))
                
        indexlist = pd.Index(pd.Timestamp(str(d)) for d in dateset)
        data = {
            'open':   openset[:],
            'close':  closeset[:],
            'high':   highset[:],
            'low':    lowset[:],
            'volume': volume[:]
        }
        klinedf = pd.DataFrame(data=data, index=indexlist)
        if fill == True and frequency == '1d':
            calender = self.getTradeDate()
            if klinedf.index[0] > calender[0]:
                left = calender.searchsorted(klinedf.index[0])
                index = calender[left:-1]
                rawdata = klinedf.reindex(index)
                zvalues = rawdata.loc[~(rawdata.volume > 0)].loc[:, 'volume']
                rawdata.update(zvalues.fillna(0))
                klinedf = rawdata.fillna(method="ffill")
            else:
                rawdata = klinedf.reindex(calender)
                zvalues = rawdata.loc[~(rawdata.volume > 0)].loc[:, 'volume']
                rawdata.update(zvalues.fillna(0))
                klinedf = rawdata.fillna(method="ffill")
        klinedf = self.__Complex_right_front(order_book_id, klinedf)
        return klinedf
    
    '''
    @function:生成股票在redis中的唯一索引
    '''
    def __generateUniqueID(self, order_book_id):
        try:
            stockid, marketid = order_book_id.split(".")
        except:
            raise RuntimeError("order_book_id {}.format is not supported".format(order_book_id))
        if marketid  not in MARKTDATA_TO_RedisDB.keys():
            raise RuntimeError("marketid {} is not supported".format(marketid))
        uniqueID = "%02d" % STDMARKT_TO_INNER[marketid] + stockid.zfill(8) + "".zfill(22)
        return uniqueID
     
    '''
    @function:生成股票在redis中的唯一索引
    '''
    def __redisPrefix(self, frequency):
        if frequency not in DATA_FREQUENCY:
            raise RuntimeError("frequency {} is not supported".format(frequency))
        if frequency == '1m':
            return "KX:MIN1KLINE:"
        if frequency == '5m':
            return "KX:MIN5KLINE:"
        if frequency == '15m':
            return "KX:MIN15KLINE:"
        if frequency == '30m':
            return "KX:MIN30KLINE:"
        if frequency == '60m':
            return "KX:MIN60KLINE:"
        if frequency == '1d':
            return "KX:HISDAYKLINE:"
    
    '''
    @function:股票数据前复权处理
    @param order_bookid: 股票代码
    @param klines: Dataframe data type 
    '''
    def __Complex_right_front(self, order_bookid, klines):
        sql = 'select code,date,sum(dividendCash) as dividendCash,sum(dividendNum) as dividendNum,sum(rationedPrice)\
                as rationPrice,sum(rationedNum) as rationNum,sum(seoNum) as seoNum,sum(seoPrice) as seoPrice, '
        sql += ' sum(trunNum) as trunNum from stock_divident_factor where code = "{0}" group by code,date order by date asc '.format(order_bookid)
        diviFactors = pd.read_sql(sql, self.conn, index_col=["date"])
        for index in diviFactors.index:
            right = klines.index.searchsorted(index, side='right')
            if right == 0:
                continue
            divKlines = klines.loc[:klines.index[right - 2], ['open', 'close', 'low', 'high']]
            divKlines = (divKlines - (diviFactors.loc[index].dividendCash) / 10.0 + (diviFactors.loc[index].rationPrice * diviFactors.loc[index].rationNum / 10.0)) / (1 + (diviFactors.loc[index].dividendNum + diviFactors.loc[index].trunNum) / 10.0)
            klines.update(divKlines)
        pd.set_option('precision', 2)
        return klines
    

if __name__ == '__main__':
    DATABASES = {
        'hqdata': {
            'engine':'mysql',
            'db': 'HqData',
            'user': 'root',
            'password': 'zhw1519',
            'host': '192.168.7.188',
            'port': 3306
        }
    }    
#     '''
#     @function:获取时间区间内的交易分钟数,智能跳过节假日以及大盘不开盘的日期
#     @param:start_date: 开始日期
#     @param:end_date:截至日期
#     ''' 
#     def get_trading_minutes(start_time, end_time):
#         left_date = dates.searchsorted(start_time)
#         right_date = dates.searchsorted(end_time, side='right')
#         trade_dates = dates[left_date:right_date]
#         minutes = pd.DatetimeIndex([])
#         for trade_date in trade_dates:
#             periord_begin_1 = str(trade_date) + ' 09:31:00';
#             periodr_end_1 = str(trade_date) + ' 11:30:00';
#             periord_begin_2 = str(trade_date) + ' 13:00:00';
#             periodr_end_2 = str(trade_date) + ' 15:00:00';          
#             data1 = pd.date_range(periord_begin_1, periodr_end_1, freq='T')
#             data2 = pd.date_range(periord_begin_2, periodr_end_2, freq='T')
#             minutes = minutes.append(data1)
#             minutes = minutes.append(data2)
#         left_minutes = minutes.searchsorted(start_time)
#         right_minutes = minutes.searchsorted(end_time, side='right')
#         return minutes[left_minutes:right_minutes]
#     
#     minute = get_trading_minutes('2016-8-16', '2016-8-17')
#     print(minute)
#     import MySQLdb
#     import time
#     time1 = time.time()
#     config = RedisConfig(host='120.55.204.103', port=6379, db=0, password='redisserver')
#     redisReader = RedisDataReader(config)
#     order_bookid = '600869.XSHG' 
#     klines = redisReader.getAllKlineData(order_bookid, '1d', True)
#     time2 = time.time()
# #     print klines["2014-01-01":] 
# #     conn = MySQLdb.connect(host=DATABASES["hqdata"].get("host"), user=DATABASES["hqdata"].get("user"), passwd=DATABASES["hqdata"].get("password"), db=DATABASES["hqdata"].get("db"), charset="utf8")
# #     sql = 'select code,date,sum(dividendCash) as dividendCash,sum(dividendNum) as dividendNum,sum(rationedPrice) as rationPrice,sum(rationedNum) as rationNum,sum(seoNum) as seoNum,sum(seoPrice) as seoPrice, '
# #     sql += ' sum(trunNum) as trunNum from stock_divident_factor where code = "{0}" group by code,date order by date asc '.format(order_bookid)
# #      
# #     diviFactors = pd.read_sql(sql, conn, index_col=["date"])
# #     for index in diviFactors.index:
# #         right = klines.index.searchsorted(index, side='right')
# #         if right == 0:
# #             continue
# #         divKlines = klines.loc[:klines.index[right - 2], ['open', 'close', 'low', 'high']]
# #         divKlines = (divKlines - (diviFactors.loc[index].dividendCash) / 10.0 + (diviFactors.loc[index].rationPrice * diviFactors.loc[index].rationNum / 10.0)) / (1 + (diviFactors.loc[index].dividendNum + diviFactors.loc[index].trunNum) / 10.0)
# #         klines.update(divKlines)
#     print klines
#     print time2 - time1
